Super Mario Bros. Hacking Document 1.0 --------------------------------- All data found/cracked by Dahrk Daiz (DahrkDaiz@hotmail.com) Reproduction of this document is forbidden. Copyright (C) 2003 Level Header ---------------------------- The first two bytes of a level are it's level header. The level header is broken up like this: ( byte 1 ) ( byte 2 ) t t a p p b b b - c c s s g g g g =================================|===================| |_| | |_| |_|_| |_| |_| |_|_|_|| ground/block | | | | | | | |___| type | | | | | | | |===================| | | | | | |_________| scenery | | | | | | | type | | | | | | |===================| | | | | |_____________| compliment | | | | | | | | | | | |===================| | | | |____________________| background/season | | | | | type | | | | |===================| | | |_________________________| starting | | | | position | | | |===================| | |____________________________| auto walk | | | on/off | | |===================| |_______________________________| time | | | =====================================================| ground/block type: defines the type of ground structure for a level, this can be how high the ground is and how low the ceiling goes (if there is a ceiling). scenery type: determines what will be put in the background clouds 00 = none 01 = clouds 10 = mountains/hills 11 = fence/trees compliment: affects the pallete somewhat, but mainly determines what the "trees" look/act like 00 = trees 01 = mushrooms 10 = bullet bill turrets (they work too) 11 = the cloud world (the ground is a cloud) background/season type: this is mainly a pallete attribute, but does serve another purpose. When this attribute is less than 100 (0x04), the background is effected, anything higher and the pallete is affected. 000 = day time (normal pallete) 001 = underwater background 010 = caste wall background 011 = over water background 100 = night time 101 = day time/snow 110 = night time/ snow 111 = black and white (castle) starting position: determines where Mario starts a level. 00 = falling from sky 01 = starting on the ground 10 = falling from the sky 11 = middle of screen autowalk: determines whether Mario starts the stage walking automatically (happens in 1-2, 2-2, 4-2 and 7-2 during pipe sequence) 0 = no 1 = yes time: determines starting time 00 = 0 01 = 400 10 = 300 11 = 200 Level Format =============== The Level data is a bit odd. Each object takes 2 bytes as so: ( byte 1 ) ( byte 2 ) x x x x y y y y - p o o o o o o o ================================================= |_|_|_| |_|_|_| | |_|_|_|_|_|_| | object | | | | |_______| | | | | |=============| | | |_______________| new page | | | | flag | | | |=============| | |______________________| y | | | position | | |=============| |______________________________| x | | position | ================================================| object: this is just that, the object that will appear on the level screen, some object values put multiple of the same object on the screen. for pipes (0x70 - 0x7F), the first half (0x70 - 0x77) is a pipe you cannot enter, but the second half (0x78 - 0x7F) are enterable. new page flag: determines whether the object is the first one to appear on a new page (screen). y position*: the y position of where an object will appear (by a multiple of 16 pixels) x position: the x position of where an object will appear (by a multiple of 16 pixels) The level format is divided into "pages", so that only a small amount of level data is in RAM at any given time. The new page flag bit tells the game that the object it is set on is the first object in the page. Then, every object after that will appear on the same page until a new page bit is found. However, there are limits to this. If 3 objects are on the same x position for the same page, every object following that will not show up. *The Y position serves a second purpose, if the y position is beyond 1011 (0x0B) then the object set is changed. If y position is 0x0C, a new set of objects are used (but the Y position of these new sets of objects cannot be changed). Each increment of Y position is a new set of objects. The end of a level is represented by the XY byte being 0xFD Enemy Format ================ The enemy data has no header and works almost the same way as the level data format. ( byte 1 ) ( byte 2 ) x x x x y y y y - p e e e e e e e ================================================= |_|_|_| |_|_|_| | |_|_|_|_|_|_| | enemy | | | | |_______| | | | | |=============| | | |_______________| new page | | | | flag | | | |=============| | |______________________| y | | | position | | |=============| |______________________________| x | | position | ================================================| enemy: this is just that, the enemy that will appear on the level screen, some enemy values put multiple of the same enemies on the screen. new page flag: determines whether the enemy is the first one to appear on a new page (screen). y position*: the y position of where an enemy will appear (by a multiple of 16 pixels). This position CANNOT be 0x0E. That's explained later. x position: the x position of where an enemy will appear (by a multiple of 16 pixels) The enemy format is divided into "pages", so that only a small amount of enemy data is in RAM at any given time. The new page flag bit tells the game that the enemy it is set on is the first enemy in the page. Then, every enemy after that will appear on the same page until a new page bit is found. *The Y position serves a second purpose, if the position is at it's maximum (0x0F) then that tells the game to skip a certain number of pages before reading more enemy data, however, the number of pages to skip isn't quite clear yet. The enemy data for a level ends when the XY byte is FF. Pipe Pointers ======================= Pipe pointers work in a very odd way. First of all, they aren't true pointers, rather, they point to maps (levels) and the page for that map. When a pipe pointer is placed on a level, the page it's on and every page after that makes enterable pipes go to that page/level. The only thing that can change it is another pipe pointer, which cancels the previous one and actives for every page afterwards. Pipe pointers are different in that they take up 3 bytes, rather than 2. x x x x y y y y - n m m m m m m m - w w w p p p p p ====================================================================| |_|_|_| |_|_|_| | |_|_|_|_|_|_| |_|_| |_|_|_|_| | page | | | | | | |_____| pointer | | | | | | |===============| | | | | |_____________| world | | | | | | active | | | | | |===============| | | | |_________________________| map | | | | | pointer | | | | |===============| | | |_________________________________| new page | | | | flag | | | |===============| | |________________________________________| y position | | | (always 0x0E) | | |===============| |________________________________________________| x position | | | ====================================================================| page pointer: The page at which you will appear at after entering the pipe. The actual position is about 2 blocks above the ground and 2 blocks to the right of the left screen. world active: This determines the world that the pipe pointer works on. In SMB1, the value 0x00 is world 1, this 0x07 is world 8. If a pipe pointer appears on world 3, but the world active value is for world 6, then the pipe pointer is ignored. map pointer: The map number of the level that will be loaded, note, maps correspond to level types and real pointers, which will be explained later. new page flag: the same flag that's used for objects and enemies that says that it is the first enemy on the page. y position: always 0x0E x position: doesn't matter for pipe pointers Maps =========================== Levels aren't loaded directly from pointers like in many games. Instead, they're loaded from map values. A map value corresponds to a level pointer table, enemy pointer table and a level "type". Maps 0x00 - 0x1F are water types, 0x20 - 0x3F are grassland, 0x40 - 0x5F are underground and 0x60 - 0x7F are castle types. Afterwards, the pattern repeats (i.e. 0x80 - 0x9F are water, etc). The pointer table that the maps use to load a level are stored in two seperate pieces. The low byte of the pointer table begins at 0x9D2C in the ROM, the high byte starts at 0x9D4E. This works as well with the enemy pointer table. The low byte starts at 0x9CE4 and the high byte starts at 0x9D06. What part of the table the maps actually point to though are unknown to me right now. I use a debugger generally to find the actually addresses of levels. There's also a map table that determines the order the maps are loaded. This begins at 0x1CCC at the ROM, with 0x25 being 1-1, 0x29 being 1-2 (intro) and so on. In the level data, there's an object of an reverse L shaped pipe. This pipe is of only 1 size. This pipe is special in that when entered, it increases the pointer to the map table by 1. The map pointer begins as such: 0x1CCC: 25 29 C0 29 is level 1-2's intro, in that intro, there's a pipe Mario enters, it's that reverse L pipe that makes the pointer move up 1 byte. Thus entering the pipe changes the current map to C0 (1-2 underground). Note, only 1 un-resizable reverse L pipe does this, the resizable one acts just like a normal pipe and obeys the pipe pointers. Just before the map table is a table of World offsets. This table determines how many bytes on the table to start when loading a level. What the game does is load a value from the world map offset then add the current stage to that (0, 1, 2, etc). This begins at 0x1CC4 with 00 05 0A etc. Noticed world 2's offset is 05. Remember, the reverse L pipe will increase the stage number, so technically, World 1 has 5 stages, same with World 2, World 4 and World 7.